package com.magist.manage.copyrights.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.magist.core.entity.CxtHolder;
import com.magist.core.entity.Page;
import com.magist.core.exception.BusinessException;
import com.magist.core.service.SimpleServiceImpl;
import com.magist.core.util.BeanCompareUtil;
import com.magist.core.util.BeanCopyUtil;
import com.magist.core.util.MAssertUtil;
import com.magist.core.util.ObjectCheckUtil;
import com.magist.manage.copyrights.dao.SupplyInfoMapper;
import com.magist.manage.copyrights.dto.SupplyInfoDto;
import com.magist.manage.copyrights.dto.SupplyLinkMansDto;
import com.magist.manage.copyrights.entity.SupplyInfo;
import com.magist.manage.copyrights.entity.SupplyLinkMans;
import com.magist.manage.copyrights.service.SupplyInfoService;
import com.magist.manage.copyrights.service.SupplyLinkMansService;
import com.magist.manage.enums.OpActionEnum;
import com.magist.manage.enums.OpTypeEnum;
import com.magist.manage.enums.OrganizationTypeEnum;
import com.magist.manage.enums.SupplyLevelEnum;
import com.magist.manage.enums.SupplyStatusEnum;
import com.magist.manage.enums.SupplyTypeEnum;
import com.magist.manage.util.BusinessLogUtil;
import com.magist.manage.web.entity.UserInfo;
import com.magist.manage.web.service.UserInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.LinkedList;
import java.util.List;

@Service
public class SupplyInfoServiceImpl extends SimpleServiceImpl<SupplyInfo> implements SupplyInfoService{

	@Autowired
	private SupplyInfoMapper supplyInfoMapper;
    @Autowired
	private SupplyLinkMansService supplyLinkMansService;
    @Autowired
	private UserInfoService userInfoService;
	@Autowired
    private BusinessLogUtil businessLogUtil;

	@Override
	public PageInfo<SupplyInfo> page(Example example, Page page) {
		String orderBy = page.getSort() + " " + page.getOrder();
		if(StringUtils.isEmpty(orderBy.trim())) {
			PageHelper.startPage(page.getCurrPage(), page.getLimit());
		} else {
			PageHelper.startPage(page.getCurrPage(), page.getLimit(),orderBy);
		}
    	List<SupplyInfo> list = this.find(example);
        PageInfo<SupplyInfo> pageInfo = new PageInfo(list);
		return pageInfo;
	}

	@Override
	public PageInfo<SupplyInfo> page(SupplyInfo supplyInfo, Page page) {
		String orderBy = page.getSort() + " " + page.getOrder();
		if(StringUtils.isEmpty(orderBy.trim())) {
			PageHelper.startPage(page.getCurrPage(), page.getLimit());
		} else {
			PageHelper.startPage(page.getCurrPage(), page.getLimit(),orderBy);
		}
		List<SupplyInfo> list = this.find(supplyInfo);
		PageInfo<SupplyInfo> pageInfo = new PageInfo(list);
		return pageInfo;
	}

	@Override
	public void addSupply(SupplyInfoDto supplyInfoDto) {
    	if(supplyInfoDto.getPersonId()!=null){
			UserInfo userInfo=userInfoService.getById(supplyInfoDto.getPersonId());
			if(userInfo!=null){
				supplyInfoDto.setPersonName(userInfo.getUserName());
			}
		}
		// 校验参数
    	this.check(supplyInfoDto);

    	this.doInsertSupplyInfo(supplyInfoDto);
	}

	private void doInsertSupplyInfo(SupplyInfoDto supplyInfoDto) {
		List<SupplyLinkMansDto> supplyLinkMans = supplyInfoDto.getSupplyLinkMans();
		SupplyInfo supplyInfo = new SupplyInfo();
		BeanUtils.copyProperties(supplyInfoDto,supplyInfo);
//		supplyInfo.setEntryDate(DateUtil.parse(supplyInfoDto.getEntryDate(),"EEE MMM dd HH:mm:ss zzz yyyy"));
		String id = supplyInfoDto.getId();
		if(!StringUtils.isEmpty(id)) {
			try {
				String compare = BeanCompareUtil.compare(BeanCopyUtil.copy(this.getById(id),SupplyInfoDto.class), supplyInfoDto);
				businessLogUtil.recordBusinessLog(OpActionEnum.EDIT.getCode(),OpTypeEnum.SupplyInfo.getCode(),supplyInfoDto.getId(),"修改供应商:" + supplyInfoDto.getCompanyName(),compare);
			} catch (Exception e) {
				e.printStackTrace();
			}

			this.update(supplyInfo);
		} else {
			supplyInfo.setId(getNewId());
			try {
				String info = BeanCompareUtil.info(BeanCopyUtil.copy(supplyInfo, SupplyInfoDto.class));
				businessLogUtil.recordBusinessLog(OpActionEnum.ADD.getCode(),OpTypeEnum.SupplyInfo.getCode(),supplyInfo.getId(),"新增供应商:" + supplyInfo.getCompanyName(),info);
			} catch (Exception e) {
				e.printStackTrace();
			}

			this.insert(supplyInfo);
		}
		supplyInfoDto.setId(supplyInfo.getId());

	}

	@Override
	public int updateSupplyInfo(SupplyInfoDto supplyInfoDto) {
		// 校验参数
    	this.check(supplyInfoDto);

		String supplyId = supplyInfoDto.getId();
		MAssertUtil.notNull(supplyId,"供应商更新操作主键不能为空");

		SupplyInfo oldSupplyInfo = this.getById(supplyInfoDto.getId());
		SupplyInfoDto oldDto = BeanCopyUtil.copy(oldSupplyInfo, SupplyInfoDto.class);
		SupplyInfo supplyInfo = new SupplyInfo();
		BeanUtils.copyProperties(supplyInfoDto,supplyInfo);
		supplyInfo.setModifyTime(oldSupplyInfo.getModifyTime());
		this.update(supplyInfo);
		List<SupplyLinkMansDto> supplyLinkMans = supplyInfoDto.getSupplyLinkMans();

		supplyLinkMans.forEach(supplyLinkMan -> {
			String linkManId = supplyLinkMan.getId();
			if(StringUtils.isEmpty(linkManId)) {
				// 插入
				SupplyLinkMans linkMans = new SupplyLinkMans();
				BeanUtils.copyProperties(supplyLinkMan,linkMans);
				linkMans.setSupplyId(supplyId);
				linkMans.setId(supplyLinkMansService.getNewId());
				supplyLinkMansService.insert(linkMans);
			} else {
				// 更新
				SupplyLinkMans oldLinkMans = supplyLinkMansService.getById(linkManId);
				SupplyLinkMans linkMans = new SupplyLinkMans();
				BeanUtils.copyProperties(supplyLinkMan,linkMans);
				linkMans.setSupplyId(supplyId);
				linkMans.setModifyTime(oldLinkMans.getModifyTime());
				supplyLinkMansService.update(linkMans);
			}

		});

		try {
			String compare = BeanCompareUtil.compare(oldDto, supplyInfoDto);
			businessLogUtil.recordBusinessLog(OpActionEnum.EDIT.getCode(),OpTypeEnum.SupplyInfo.getCode(),supplyInfoDto.getId(),"修改供应商:" + supplyInfoDto.getCompanyName(),compare);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return 1;

	}

	private void check(SupplyInfoDto supplyInfoDto) {
		MAssertUtil.notNull(supplyInfoDto.getUsrName(),"用户名为空");
		MAssertUtil.shorterThan(supplyInfoDto.getUsrName(),17,"用户名超过16位");
		MAssertUtil.notNull(supplyInfoDto.getNickName(),"简称为空");
		MAssertUtil.shorterThan(supplyInfoDto.getNickName(),21,"简称超过20位");
		MAssertUtil.notNull(supplyInfoDto.getCompanyName(),"供应商官方名称为空");
		MAssertUtil.shorterThan(supplyInfoDto.getCompanyName(),31,"供应商官方名称超过30位");
		Assert.notNull(supplyInfoDto.getOrganizationType(), "机构类型为空");
		Assert.notNull(supplyInfoDto.getSupplyType(), "供应商类型为空");
		Assert.notNull(supplyInfoDto.getStatus(), "供应商类型为空");
		Assert.notNull(supplyInfoDto.getSupplyLevel(),"评级为空");
		Assert.notNull(supplyInfoDto.getPersonName(),"对接人为空");
		Assert.notNull(supplyInfoDto.getEntryDate(),"入驻日期为空");
//		Assert.notNull(supplyInfoDto.getLogoImg(),"LOGO为空");
		Assert.notNull(supplyInfoDto.getPersonId(),"对接人ID为空");
//		Assert.notNull(supplyInfoDto.getAddress(),"供应商地址为空");
//		Assert.notNull(supplyInfoDto.getBackground(),"背景特点为空");
		Assert.notNull(supplyInfoDto.getUsrName(),"用户名为空");

		MAssertUtil.isNumOrLetter(supplyInfoDto.getUsrName(),"用户名请填写字母和数字");
		MAssertUtil.isLetterOrChinese(supplyInfoDto.getNickName(),"简称请填写字母和汉字");
		MAssertUtil.isNumOrLetterOrChinese(supplyInfoDto.getCompanyName(),"公司名称请填写字母或汉字或数字");
		MAssertUtil.nullOrShorterThan(supplyInfoDto.getAddress(), 200, "地址内容太长");
		MAssertUtil.nullOrShorterThan(supplyInfoDto.getBackground(), 200, "背景特点内容太长");


//		List<SupplyLinkMansDto> supplyLinkMans = supplyInfoDto.getSupplyLinkMans();
//		MAssertUtil.hasSize(supplyLinkMans,"联系人为空");
//		supplyLinkMans.forEach(supplyLinkMan -> {
//			Assert.notNull(supplyLinkMan.getLinkName(),"联系人姓名为空");
//			Assert.notNull(supplyLinkMan.getLinkMobile(),"联系人电话为空");
//		});
		if (CxtHolder.getUser() != null) {
			supplyInfoDto.setModifier(CxtHolder.getUser().getUserName());
		}

		// 判断名称是否重复
		String nickName = supplyInfoDto.getNickName();
		String id = supplyInfoDto.getId();
		this.checkDataDup(id,nickName);



	}

	private void checkDataDup(String id, String nickName) {
		if(!StringUtils.isEmpty(id)) {
			SupplyInfo oldSupplyInfo = this.getById(id);
			String oldNickName = oldSupplyInfo.getNickName();
			if (oldNickName.equals(nickName)) {
				return;
			}
		}
		List<SupplyInfo> supplyInfos = this.findByNickName(nickName);
		if (!CollectionUtils.isEmpty(supplyInfos)) {
			throw new BusinessException("供应商简称重复");
		}
	}

	@Override
	public List<SupplyInfo> findByNickName(String nickName) {
		SupplyInfo supplyInfo = new SupplyInfo();
		supplyInfo.setNickName(nickName);
    	return this.find(supplyInfo);
	}

	@Override
	public void doBatchAdd(List<SupplyInfoDto> supplyInfoDtos) {
		List<String> nickNames = new LinkedList<String>();
		for (int i = 0; i < supplyInfoDtos.size(); i++) {
			SupplyInfoDto supplyInfoDto = supplyInfoDtos.get(i);
			if(ObjectCheckUtil.isAllFieldNull(supplyInfoDto)) {
				supplyInfoDtos.remove(supplyInfoDto);
				i--;
				continue;
			}
			try {
				this.checkImport(supplyInfoDto);
				// 供应商简称防重复
				String nickName = supplyInfoDto.getNickName();
				if(nickNames.contains(nickName)) {
					throw new BusinessException("导入供应商简称重复");
				} else {
					nickNames.add(nickName);
				}
			} catch (Exception e) {
				throw new BusinessException("第" + (i + 1) + "条数据错误," + e.getMessage());
			}
		}
		businessLogUtil.recordBusinessLog(OpActionEnum.IMPORT.getCode(),OpTypeEnum.SupplyInfo.getCode(),null,"导入供应商开始","批量导入供应商开始,需导入" + supplyInfoDtos.size()+"条记录");
		supplyInfoDtos.forEach(supplyInfoDto->this.doInsertSupplyInfo(supplyInfoDto));
		businessLogUtil.recordBusinessLog(OpActionEnum.IMPORT.getCode(),OpTypeEnum.SupplyInfo.getCode(),null,"导入供应商结束","批量导入供应商结束,共导入" + supplyInfoDtos.size()+"条记录");

	}

	private void checkImport(SupplyInfoDto supplyInfoDto) {
		String status = supplyInfoDto.getStatus();
		String supplyType = supplyInfoDto.getSupplyType();
		String organizationType = supplyInfoDto.getOrganizationType();
		String supplyLevel = supplyInfoDto.getSupplyLevel();
		String personName = supplyInfoDto.getPersonName();

		MAssertUtil.notNull(supplyInfoDto.getUsrName(),"用户名为空");
		MAssertUtil.shorterThan(supplyInfoDto.getUsrName(),17,"用户名超过16位");
		MAssertUtil.notNull(supplyInfoDto.getNickName(),"简称为空");
		MAssertUtil.shorterThan(supplyInfoDto.getNickName(),21,"简称超过20位");
		MAssertUtil.notNull(supplyInfoDto.getCompanyName(),"供应商官方名称为空");
		MAssertUtil.shorterThan(supplyInfoDto.getCompanyName(),31,"供应商官方名称超过30位");
		Assert.notNull(organizationType, "机构类型为空");
		Assert.notNull(supplyType, "供应商类型为空");
		Assert.notNull(status, "供应商状态为空");
		Assert.notNull(supplyLevel,"评级为空");
		Assert.notNull(personName,"对接人为空");
		Assert.notNull(supplyInfoDto.getEntryDate(),"入驻日期为空");
		Assert.notNull(supplyInfoDto.getUsrName(),"用户名为空");
		// 判断枚举是否存在
		MAssertUtil.notNull(SupplyStatusEnum.getByCode(status),"供应商状态填写错误");
		MAssertUtil.notNull(SupplyTypeEnum.getByCode(supplyType),"供应商类型填写错误");
		MAssertUtil.notNull(OrganizationTypeEnum.getByCode(organizationType),"机构类型填写错误");
		MAssertUtil.notNull(SupplyLevelEnum.getByCode(supplyLevel),"评级填写错误");
		MAssertUtil.notNull(SupplyLevelEnum.getByCode(supplyLevel),"评级填写错误");

		MAssertUtil.isNumOrLetter(supplyInfoDto.getUsrName(),"用户名请填写字母和数字");
		MAssertUtil.isLetterOrChinese(supplyInfoDto.getNickName(),"简称请填写字母和汉字");
		MAssertUtil.isNumOrLetterOrChinese(supplyInfoDto.getCompanyName(),"公司名称请填写字母或汉字或数字");
		MAssertUtil.nullOrShorterThan(supplyInfoDto.getAddress(), 200, "地址内容太长");
		MAssertUtil.nullOrShorterThan(supplyInfoDto.getBackground(), 200, "背景特点内容太长");


		// 头像设置默认
		if(StringUtils.isEmpty(supplyInfoDto.getLogoImg())) {
			supplyInfoDto.setLogoImg("https://wpimg.wallstcn.com/577965b9-bb9e-4e02-9f0c-095b41417191");
		}
		// 导入从数据库中查询
		List<UserInfo> userInfo = userInfoService.findByUserName(personName);
		if (CollectionUtils.isEmpty(userInfo)) {
			throw new BusinessException("查询不到对接人");
		} else if (userInfo.size()>1) {
			throw new BusinessException("查询到多个对接人");
		} else {
			supplyInfoDto.setPersonId(userInfo.get(0).getId());
		}

		if (CxtHolder.getUser() != null) {
			supplyInfoDto.setModifier(CxtHolder.getUser().getUserName());
		}
		this.checkDataDup(supplyInfoDto.getId(), supplyInfoDto.getNickName());
	}

	@Override
	public int insert(SupplyInfo entity) {
		if (CxtHolder.getUser() != null) {
			entity.setModifier(CxtHolder.getUser().getUserName());
		}
		return super.insert(entity);
	}

	@Override
	public int update(SupplyInfo entity) {
		if (CxtHolder.getUser() != null) {
			entity.setModifier(CxtHolder.getUser().getUserName());
		}
		return super.update(entity);
	}

	@Override
	public List<SupplyInfo> findByCreateById(String userId) {
		if(StringUtils.isEmpty(userId)) {
			return null;
		}
		SupplyInfo supplyInfo = new SupplyInfo();
		supplyInfo.setCreateById(userId);
		return this.find(supplyInfo);
	}
}